home *** CD-ROM | disk | FTP | other *** search
- /*-------
- * Kurta "Series One" driver
- *
- * Please do not look too closely at this code, as it could
- * cause health problems for those who cannot tolerate a lot
- * of laughing. In other words, this codes is pretty ugly
- * and probably wont be of much use to anyone.
- * If you make any changes to this driver, please let me know
- * what you did to improve/change it. The driver does need a
- * lot of work, but is does it's minimal job of sending mouse
- * events.
- */
- #include <DOS/DOS.h>
- #include <Devices/Serial.h>
- #include <Devices/Input.h>
- #include <Devices/InputEvent.h>
- #include <Exec/IO.h>
- #include <Exec/Lists.h>
- #include <Exec/Memory.h>
- #include <Exec/Devices.h>
- #include <Exec/Libraries.h>
- #include <Libraries/Commodities.h>
- #include <Libraries/DOSExtens.h>
- #include <WorkBench/Startup.h>
- #include <CLib/ALib_protos.h>
- #include <Proto/Commodities.h>
- #include <Proto/DOS.h>
- #include <Proto/Exec.h>
- #include <Proto/Intuition.h>
-
- #define ABSEXECBASE ((struct ExecBase **)4L)
-
- #define READ_BUFFER 5 // Each command is 5 bytes long.
- /*------------------ FORMAT3 Settings -----------------------------*/
- #define BUTTON_GRN 1 // m 0001 m = Menu
- #define BUTTON_RED 2 // m 0010 bit 7 always = 1
- #define BUTTON_BLU 4 // m 0100 bit 6 always = 0
- #define BUTTON_YLW 8 // m 1000
- #define MENUSTRIP 32 // M xxxx bit 4 = menu Y/N
- #define CMD_SIZE 7 // Hi bits shifted Left 6 (128).
- #define MAXVALUE 127 // = 1<<CMD_SIZE-1
- /*------------------------------------------------------------------*/
- #define BUTTONS (BUTTON_GRN|BUTTON_RED|BUTTON_BLU|BUTTON_YLW)
- #define BUTTON_MID BUTTON_RED
- #define BUTTON_LEFT BUTTON_GRN // Its not the left, but it is always Button 1
- #define BUTTON_DOWN BUTTON_BLU
- #define BUTTON_RIGHT BUTTON_YLW
- #define MY_MOUSEMOVE 1 // If any values change from
- #define MY_BUTTONEVENT 2 // the previous, then I must send
- #define MENU_FUNCTION 4 // an InputEvent to handler.
- #define TABLET_LORES 1200 // 100ppi for 12inches
- #define TABLET_HIRES 2400 // 200ppi for 12inches
-
- struct Command
- {
- UBYTE Buttons; // Value = 1, 2, 4, 8, or 0-15 combo.
- UBYTE pButtons; // Previous buttons. Used for MOUSEUP/DOWN changes.
- UBYTE Menu; // Menu F0-F11
- UBYTE MButtons; // Keep menu button presses separate.
- WORD X, Y; // Coordinates
- WORD pX, pY; // Previous coordinates. Used for DELTA values.
- };
-
- struct DosLibrary *DOSBase;
- struct IntuitionBase *IntuitionBase;
- struct Library *CxBase, *IconBase;
- extern struct WBStartup *WBenchMsg;
-
- UWORD GetKurta(UBYTE *, struct Command *);
- ULONG DoKMenu(struct Command *);
-
- BOOL ExitFlag = 0;
- struct MsgPort *broker_mp;
- CxObj *broker, *filter, *sender, *translate;
- struct NewBroker newbroker =
- {
- NB_VERSION,
- "Kurta_Driver",
- "Kurta Drawing Pad Driver",
- "Commodity for Kurta Drawing Pad",
- NBU_UNIQUE | NBU_NOTIFY,
- 0, 0, 0, 0
- };
- struct InputEvent *ie;
- ULONG cxsigflag;
-
- __saveds Kurta(void)
- {
- struct IOExtSer *sio; // Serial IO request.
- struct MsgPort *smp; // Serial MsgPort.
- struct IOStdReq *iio; // Input IO request.
- struct MsgPort *imp; // Input MsgPort.
- struct InputEvent *myevent; // My fake input event.
- struct IEPointerTablet *iep; // My new pointer pixel positions.
- struct Command c; // What happened on the tablet.
- UBYTE readbuffer[READ_BUFFER]; // Serial data from tablet.
- ULONG result;
- ULONG waitmask;
- UWORD kevent; // Has there been any events from Kurta()?
- UWORD bmask; // Holds which buttons have changed since last message.
- ULONG msgid, msgtype;
- CxMsg *msg;
-
- struct Process *proc;
- struct Message *WBMsg = NULL;
-
- proc = (struct Process *)FindTask(NULL); // Who/Where am I?
- if( !proc->pr_CLI ) // Am I started from a CLI?
- {
- WaitPort(&proc->pr_MsgPort); // NO? Well then get WBStartup Msg.
- WBMsg = GetMsg(&proc->pr_MsgPort);
- }
-
- DOSBase=(struct DosLibrary *)OpenLibrary("dos.library", 37);
- if( !DOSBase ) // No startup code, get DOSBase my self
- return(-1);
-
- if( smp = (struct MsgPort *)CreatePort("Kurta_Serial", 0) )
- {
- if( imp = (struct MsgPort *)CreatePort("Kurta_Input", 0) )
- {
- if( sio=(struct IOExtSer *)CreateExtIO(smp, sizeof(struct IOExtSer)) )
- {
- if( myevent= (struct InputEvent *)AllocVec(sizeof(struct InputEvent), MEMF_PUBLIC) )
- {
- if( iep = (struct IEPointerTablet *)AllocVec(sizeof(struct IEPointerTablet), MEMF_PUBLIC) )
- {
- if (iio = (struct IOStdReq *)CreateIORequest(imp,sizeof(struct IOStdReq)))
- {
- if( !OpenDevice("input.device", NULL,
- (struct IORequest *)iio, NULL) )
- {
- if( IntuitionBase = (struct IntuitionBase *)
- OpenLibrary("intuition.library", 36L) )
- {
- sio->io_SerFlags = 0;
- if( !OpenDevice(SERIALNAME, NULL, sio, NULL) )
- {
- sio->IOSer.io_Command = SDCMD_SETPARAMS;
- sio->io_SerFlags &= ~SERF_PARTY_ON;
- sio->io_SerFlags |= SERF_XDISABLED | SERF_SHARED;
- sio->io_Baud = 9600;
- if( !(result=DoIO(sio)) )
- {
- /*** Put commodity startup here ***/
- if (CxBase = OpenLibrary("commodities.library", 37L))
- {
- if (broker_mp = CreateMsgPort())
- {
- newbroker.nb_Port = broker_mp;
-
- if (broker = CxBroker(&newbroker, NULL))
- {
- ActivateCxObj(broker, 1L);
-
- waitmask = SIGBREAKF_CTRL_C | 1L<<smp->mp_SigBit | (1L << broker_mp->mp_SigBit);
- /*---------------Initialization complete------------------------------------*/
- /* Now just wait until data comes in, or user breaks. */
- while( !ExitFlag )
- {
- sio->IOSer.io_Command = CMD_READ;
- sio->IOSer.io_Length = READ_BUFFER;
- sio->IOSer.io_Data = (APTR)readbuffer;
- SendIO(sio);
- result = Wait(waitmask); // Sit and wait...
- if( ExitFlag||(result & SIGBREAKF_CTRL_C) ) // Quit
- break;
- if( result & (1L<<broker_mp->mp_SigBit) )
- {
- while(msg = (CxMsg *)GetMsg(broker_mp))
- {
-
- msgid = CxMsgID(msg);
- msgtype = CxMsgType(msg);
- ReplyMsg((struct Message *)msg);
-
- switch(msgtype)
- {
- case CXM_IEVENT:
- /* Shouldn't get any of these in this example */
- break;
- case CXM_COMMAND:
- /* Commodities has sent a command */
- switch(msgid)
- {
- case CXCMD_DISABLE:
- /* The user clicked Commodities Exchange disable
- * gadget better disable
- */
- ActivateCxObj(broker, 0L);
- break;
- case CXCMD_ENABLE:
- /* user clicked enable gadget */
- ActivateCxObj(broker, 1L);
- break;
- case CXCMD_KILL:
- /* user clicked kill gadget, better quit */
- ExitFlag=TRUE;
- break;
- }
- break;
- default:
- // kprintf("Unknown msgtype\n");
- break;
- }
- break;
- }
- }
-
- if( CheckIO(sio) )
- {
- WaitIO(sio);
- if( sio->IOSer.io_Actual = 5 )
- {
- kevent = GetKurta(readbuffer, &c);
- if( kevent&MENU_FUNCTION )
- {
- if( c.Menu==11 )
- {
- ExitFlag = TRUE;
- break;
- }
- myevent->ie_Class = IECLASS_RAWKEY; /* new mouse pos */
- myevent->ie_SubClass = NULL;
- myevent->ie_Code = c.Menu+0x4F;
- myevent->ie_Qualifier = NULL;
- myevent->ie_EventAddress = (APTR)iep; /* IEPointerTablet */
- myevent->ie_NextEvent = NULL;
- iio->io_Data = (APTR)myevent; /* InputEvent */
- iio->io_Length = sizeof(struct InputEvent);
- iio->io_Command = IND_WRITEEVENT;
-
- DoIO((struct IORequest *)iio);
- }
- //result = DoKMenu(&c);
- else
- {
- if( kevent & MY_MOUSEMOVE )
- {
- myevent->ie_Class = IECLASS_NEWPOINTERPOS; /* new mouse pos */
- myevent->ie_SubClass = IESUBCLASS_TABLET; /* on pixel */
- myevent->ie_Code = IECODE_NOBUTTON;
- myevent->ie_Qualifier = NULL;
- myevent->ie_EventAddress = (APTR)iep; /* IEPointerTablet */
- myevent->ie_NextEvent = NULL;
- iio->io_Data = (APTR)myevent; /* InputEvent */
- iio->io_Length = sizeof(struct InputEvent);
- iio->io_Command = IND_WRITEEVENT;
- iep->iept_Range.X = TABLET_LORES;
- iep->iept_Range.Y = TABLET_LORES;
- iep->iept_Value.X = c.X;
- iep->iept_Value.Y = c.Y;
- iep->iept_Pressure = NULL; // Not implemented.
-
- DoIO((struct IORequest *)iio);
- }
- if( kevent & MY_BUTTONEVENT ) // TABLET cannot do Buttons.
- {
- bmask = c.Buttons ^ c.pButtons;
- myevent->ie_Class = IECLASS_RAWMOUSE;
- myevent->ie_SubClass = NULL;
- myevent->ie_Code = IECODE_NOBUTTON;
- myevent->ie_Qualifier = NULL;
- myevent->ie_EventAddress = NULL;
- myevent->ie_NextEvent = NULL;
- iio->io_Data = (APTR)myevent; /* InputEvent */
- iio->io_Length = sizeof(struct InputEvent);
- iio->io_Command = IND_WRITEEVENT;
- if( bmask & BUTTON_LEFT )
- {
- myevent->ie_Code = IECODE_LBUTTON;
- if( !(c.Buttons & BUTTON_LEFT) )
- myevent->ie_Code |= IECODE_UP_PREFIX;
- }
- else
- if( bmask & BUTTON_RIGHT )
- {
- myevent->ie_Code = IECODE_RBUTTON;
- if( !(c.Buttons & BUTTON_RIGHT) )
- myevent->ie_Code |= IECODE_UP_PREFIX;
- }
- else
- if( bmask & BUTTON_MID )
- {
- myevent->ie_Code = IECODE_MBUTTON;
- if( !(c.Buttons & BUTTON_MID) )
- myevent->ie_Code |= IECODE_UP_PREFIX;
- }
-
- DoIO((struct IORequest *)iio);
- }
- }
- }
- else return(2); // printf("Bad Command.\n");
- }
-
- }
- DisplayBeep(NULL);
- AbortIO(sio); // Clean up port and quit.
- WaitIO(sio);
- DisplayBeep(NULL);
-
- /*-----------------Cleanup starts here--------------------------------------*/
- /*** Put commodity teardown here ***/
- DeleteCxObj(broker);
-
- while(msg = (CxMsg *)GetMsg(broker_mp))
- ReplyMsg((struct Message *)msg);
- }
- DeletePort(broker_mp);
- }
- CloseLibrary(CxBase);
- }
-
- }
- else
- return(3); //printf("Could not set Serial Params.\n");
- CloseDevice(sio);
- }
- else
- return(4); //printf("Could not open serial.device.\n");
- CloseLibrary(IntuitionBase);
- }
- else
- return(5); //printf("Could not open IntuitionBase.\n");
- CloseDevice((struct IORequest *)iio);
- }
- else
- return(6); //printf("Could no OpenDevice for iio.\n");
- DeleteIORequest(iio);
- }
- else
- return(7); //printf("Could not CreateIORequest(Input).\n");
- FreeVec(iep);
- }
- else
- return(8); //printf("Could not AllocMem 'iep'.\n");
- FreeVec(myevent);
- }
- else
- return(9); //printf("Could not AllocMem for 'myevent'.\n");
- DeleteExtIO(sio);
- }
- else
- return(10); //printf("Could not Create[serial]ExtIO.\n");
- DeletePort(imp);
- }
- else
- return(11); //printf("Could not CreatePort(Kurta_Input)\.\n");
- DeletePort(smp);
- }
- else
- return(12); //printf("Could not CreatePort(Kurta_Serial)\n");
- if( DOSBase ) CloseLibrary(DOSBase);
- if( WBMsg ) // Hey! We were started from WB, clean up.
- {
- Forbid();
- ReplyMsg(WBMsg);
- Permit();
- }
-
- return(0); // Remember to exit from Main or program will continue...
- }
-
- UWORD
- GetKurta(UBYTE *cmd, struct Command *c)
- {
- UWORD event = 0;
- static UBYTE accel=0; // Immitate a mouse accelerator for the tablet.
-
- /* Save all previous stats */
- c->pX = c->X;
- c->pY = c->Y;
- c->pButtons = c->Buttons;
- if( cmd[0]&MENUSTRIP )
- {
- c->Menu = (cmd[1]&MAXVALUE) - 0x0A; // Which menu (0-11).
- c->MButtons = (cmd[0]&BUTTONS)|(cmd[2]&MAXVALUE)<<CMD_SIZE;
- if( c->Menu == 0 )
- {
- accel++; if( accel >2 ) accel = 0; // 0,1,2 (x << accel = 1, 2, 4 )
- DisplayBeep(NULL);
- }
- else
- event |= MENU_FUNCTION;
- }
- else
- {
- c->Buttons = (cmd[0]&BUTTONS); // Buttons currently pressed
- c->X = ((cmd[1]&MAXVALUE) | (cmd[2]&MAXVALUE)<<CMD_SIZE)<<accel;
- c->Y = ((cmd[3]&MAXVALUE) | (cmd[4]&MAXVALUE)<<CMD_SIZE)<<accel;
- if( c->X < 0 ) c->X = 0;
- if( c->Y < 0 ) c->Y = 0;
- if( (c->pX != c->X)||(c->pY != c->Y) ) // Send input events if
- event |= MY_MOUSEMOVE; // if any event differs
- if( c->pButtons != c->Buttons ) // from the previous.
- event |= MY_BUTTONEVENT; //
- }
-
- return(event);
- }
-
- ULONG
- DoKMenu(struct Command *c)
- {
- if( c->Menu == 11 )
- ExitFlag = TRUE;
-
- DisplayBeep(NULL);
-
- return(ExitFlag);
- }
-
-